<template>
  <div class="web-image-display">
    <!-- 图片展示区域 -->
    <div v-if="images && images.length > 0" class="image-display">
      <!-- 单张图片模式 -->
      <div v-if="displayMode === 'single'" class="single-image">
        <el-image 
          :src="getImageUrl(images[0])" 
          :fit="fit"
          class="display-image"
          :preview-src-list="[getImageUrl(images[0])]"
          preview-teleported
          @error="handleImageError"
          @load="handleImageLoad"
        >
          <!-- 加载失败显示 -->
          <template #error>
            <div class="image-error">
              <el-icon><Picture /></el-icon>
              <span>{{ errorText }}</span>
            </div>
          </template>
          
          <!-- 加载中显示 -->
          <template #placeholder>
            <div class="image-loading">
              <el-icon class="is-loading"><Loading /></el-icon>
              <span>加载中...</span>
            </div>
          </template>
        </el-image>
        
        <!-- 图片信息 -->
        <div v-if="showImageInfo" class="image-info">
          <span class="image-name">{{ getImageName(images[0]) }}</span>
          <span v-if="getImageSize(images[0])" class="image-size">{{ formatFileSize(getImageSize(images[0])) }}</span>
        </div>
      </div>
      
      <!-- 网格模式 -->
      <div v-else-if="displayMode === 'grid'" class="image-grid">
        <div 
          v-for="(image, index) in displayImages" 
          :key="image.id || index"
          class="image-item"
          @click="handleImageClick(image, index)"
        >
          <el-image 
            :src="getImageUrl(image)" 
            :fit="fit"
            class="display-image"
            :preview-src-list="previewList"
            :initial-index="index"
            preview-teleported
            @error="handleImageError"
            @load="handleImageLoad"
          >
            <!-- 加载失败显示 -->
            <template #error>
              <div class="image-error">
                <el-icon><Picture /></el-icon>
                <span>{{ errorText }}</span>
              </div>
            </template>
            
            <!-- 加载中显示 -->
            <template #placeholder>
              <div class="image-loading">
                <el-icon class="is-loading"><Loading /></el-icon>
                <span>加载中...</span>
              </div>
            </template>
          </el-image>
          
          <!-- 图片信息 -->
          <div v-if="showImageInfo" class="image-info">
            <span class="image-name">{{ getImageName(image) }}</span>
            <span v-if="getImageSize(image)" class="image-size">{{ formatFileSize(getImageSize(image)) }}</span>
          </div>
        </div>
        
        <!-- 更多图片提示 -->
        <div 
          v-if="shouldShowMoreIndicator" 
          class="image-more"
          @click="handleMoreClick"
        >
          <span>+{{ images.length - maxDisplayCount }}</span>
        </div>
      </div>
      
      <!-- 列表模式 -->
      <div v-else-if="displayMode === 'list'" class="image-list">
        <div 
          v-for="(image, index) in images" 
          :key="image.id || index"
          class="list-item"
          @click="handleImageClick(image, index)"
        >
          <el-image 
            :src="getImageUrl(image)" 
            :fit="fit"
            class="list-image"
            :preview-src-list="previewList"
            :initial-index="index"
            preview-teleported
            @error="handleImageError"
            @load="handleImageLoad"
          >
            <!-- 加载失败显示 -->
            <template #error>
              <div class="image-error">
                <el-icon><Picture /></el-icon>
                <span>{{ errorText }}</span>
              </div>
            </template>
          </el-image>
          
          <div class="list-info">
            <span class="image-name">{{ getImageName(image) }}</span>
            <span v-if="getImageSize(image)" class="image-size">{{ formatFileSize(getImageSize(image)) }}</span>
          </div>
        </div>
      </div>
      
      <!-- 图片统计信息 -->
      <div v-if="showInfo" class="display-info">
        <span class="image-count">共 {{ images.length }} 张图片</span>
        <span v-if="tipText" class="image-tip">{{ tipText }}</span>
      </div>
    </div>
    
    <!-- 空状态 -->
    <div v-else class="empty-state">
      <el-icon :size="48" color="#ccc">
        <Picture />
      </el-icon>
      <span class="empty-text">{{ emptyText }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * Web端图片展示组件
 * 生产环境标准实现，支持多种展示模式、错误处理、加载状态等功能
 * 
 * @author Wu.Liang
 * @date 2025-01-30
 * @version 1.0.0
 */

import { computed } from 'vue'
import { Picture, Loading } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

// 图片信息接口
export interface ImageInfo {
  id?: string | number
  url?: string
  fileUrl?: string
  fileName?: string
  fileSize?: number
  [key: string]: any
}

// 组件属性
interface Props {
  /** 图片列表 */
  images?: ImageInfo[]
  /** 展示模式：single-单张，grid-网格，list-列表 */
  displayMode?: 'single' | 'grid' | 'list'
  /** 图片适应方式 */
  fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down'
  /** 最大显示数量（网格模式） */
  maxDisplayCount?: number
  /** 是否显示更多提示 */
  showMoreIndicator?: boolean
  /** 是否显示图片信息 */
  showImageInfo?: boolean
  /** 是否显示统计信息 */
  showInfo?: boolean
  /** 错误提示文本 */
  errorText?: string
  /** 空状态提示文本 */
  emptyText?: string
  /** 提示文本 */
  tipText?: string
  /** 图片URL字段名 */
  urlField?: string
  /** 图片名称字段名 */
  nameField?: string
  /** 图片大小字段名 */
  sizeField?: string
  /** 是否禁用 */
  disabled?: boolean
}

// 默认属性值
const props = withDefaults(defineProps<Props>(), {
  images: () => [],
  displayMode: 'grid',
  fit: 'cover',
  maxDisplayCount: 6,
  showMoreIndicator: true,
  showImageInfo: false,
  showInfo: true,
  errorText: '加载失败',
  emptyText: '暂无图片',
  tipText: '点击图片可预览大图',
  urlField: 'fileUrl',
  nameField: 'fileName',
  sizeField: 'fileSize',
  disabled: false
})

// 事件定义
const emit = defineEmits<{
  /** 图片点击事件 */
  'image-click': [image: ImageInfo, index: number]
  /** 更多图片点击事件 */
  'more-click': [images: ImageInfo[]]
  /** 预览事件 */
  'preview': [image: ImageInfo, index: number]
  /** 错误事件 */
  'error': [data: { index?: number; image?: ImageInfo; error: any }]
  /** 加载成功事件 */
  'load': [data: { event: any }]
}>()

// 计算属性
const imageList = computed(() => {
  if (!props.images || !Array.isArray(props.images)) {
    return []
  }
  return props.images.filter(image => image && (image.url || image[props.urlField]))
})

const displayImages = computed(() => {
  if (props.displayMode === 'single') {
    return imageList.value.slice(0, 1)
  }
  if (props.displayMode === 'grid' && props.maxDisplayCount > 0) {
    return imageList.value.slice(0, props.maxDisplayCount)
  }
  return imageList.value
})

const previewList = computed(() => {
  return imageList.value.map(image => getImageUrl(image)).filter(Boolean)
})

// 是否显示更多提示
const shouldShowMoreIndicator = computed(() => {
  return props.displayMode === 'grid' && 
         props.showMoreIndicator && 
         imageList.value.length > props.maxDisplayCount
})

// 获取图片URL
const getImageUrl = (image: ImageInfo): string => {
  if (!image) return ''
  
  // 支持多种URL字段名
  const url = image[props.urlField] || image.url || image.src || image.fileUrl || ''
  
  // 确保URL是字符串
  return String(url).trim()
}

// 获取图片名称
const getImageName = (image: ImageInfo): string => {
  if (!image) return ''
  
  const name = image[props.nameField] || image.fileName || image.name || ''
  return String(name).trim() || '未命名图片'
}

// 获取图片大小
const getImageSize = (image: ImageInfo): number => {
  if (!image) return 0
  
  const size = image[props.sizeField] || image.fileSize || image.size || 0
  return parseInt(size) || 0
}

// 格式化文件大小
const formatFileSize = (fileSize: number): string => {
  if (!fileSize || fileSize === 0) {
    return '0 B'
  }
  
  const units = ['B', 'KB', 'MB', 'GB']
  let size = fileSize
  let unitIndex = 0
  
  while (size >= 1024 && unitIndex < units.length - 1) {
    size /= 1024
    unitIndex++
  }
  
  return `${size.toFixed(1)} ${units[unitIndex]}`
}

// 处理图片点击
const handleImageClick = (image: ImageInfo, index: number) => {
  if (props.disabled) return
  
  try {
    console.log('图片点击:', image, index)
    emit('image-click', image, index)
    emit('preview', image, index)
  } catch (error) {
    console.error('图片点击处理失败:', error)
    ElMessage.error('图片操作失败')
  }
}

// 处理更多图片点击
const handleMoreClick = () => {
  if (props.disabled) return
  
  try {
    const moreImages = imageList.value.slice(props.maxDisplayCount)
    console.log('更多图片点击:', moreImages)
    emit('more-click', moreImages)
  } catch (error) {
    console.error('更多图片点击处理失败:', error)
    ElMessage.error('操作失败')
  }
}

// 处理图片加载错误
const handleImageError = (error: any) => {
  console.error('图片加载失败:', error)
  emit('error', { error })
}

// 处理图片加载成功
const handleImageLoad = (event: any) => {
  console.log('图片加载成功:', event)
  emit('load', { event })
}
</script>

<style lang="scss" scoped>
.web-image-display {
  width: 100%;
}

.image-display {
  width: 100%;
}

// 单张图片模式
.single-image {
  display: flex;
  flex-direction: column;
  align-items: center;
  
  .display-image {
    max-width: 100%;
    max-height: 300px;
    border-radius: 8px;
    border: 1px solid #e4e7ed;
  }
  
  .image-info {
    margin-top: 8px;
    text-align: center;
    
    .image-name {
      display: block;
      font-size: 14px;
      color: #606266;
      margin-bottom: 4px;
    }
    
    .image-size {
      display: block;
      font-size: 12px;
      color: #909399;
    }
  }
}

// 网格模式
.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  margin-bottom: 12px;
}

.image-item {
  position: relative;
  aspect-ratio: 1;
  border-radius: 8px;
  overflow: hidden;
  background: #f5f5f5;
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }
  
  &:active {
    transform: translateY(0);
  }
  
  .display-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  
  .image-info {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
    padding: 8px;
    
    .image-name {
      display: block;
      font-size: 12px;
      color: #fff;
      margin-bottom: 2px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .image-size {
      display: block;
      font-size: 10px;
      color: rgba(255, 255, 255, 0.8);
    }
  }
}

.image-more {
  aspect-ratio: 1;
  background: rgba(0, 0, 0, 0.6);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  
  &:hover {
    background: rgba(0, 0, 0, 0.8);
  }
}

// 列表模式
.image-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.list-item {
  display: flex;
  align-items: center;
  padding: 12px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  
  &:hover {
    border-color: #409eff;
    box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
  }
  
  .list-image {
    width: 60px;
    height: 60px;
    border-radius: 4px;
    margin-right: 12px;
  }
  
  .list-info {
    flex: 1;
    
    .image-name {
      display: block;
      font-size: 14px;
      color: #606266;
      margin-bottom: 4px;
    }
    
    .image-size {
      display: block;
      font-size: 12px;
      color: #909399;
    }
  }
}

// 统计信息
.display-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #909399;
  margin-top: 8px;
  
  .image-count {
    font-weight: 500;
  }
  
  .image-tip {
    color: #409eff;
    cursor: pointer;
    
    &:hover {
      text-decoration: underline;
    }
  }
}

// 空状态
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 16px;
  
  .empty-text {
    margin-top: 12px;
    font-size: 14px;
    color: #999;
  }
}

// 错误和加载状态
.image-error,
.image-loading {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #f5f7fa;
  color: #909399;
  font-size: 12px;
  
  .el-icon {
    font-size: 20px;
    margin-bottom: 4px;
  }
}

// 响应式设计
@media screen and (max-width: 768px) {
  .image-grid {
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
    gap: 8px;
  }
  
  .list-item {
    padding: 8px;
    
    .list-image {
      width: 50px;
      height: 50px;
      margin-right: 8px;
    }
  }
}

@media screen and (min-width: 1200px) {
  .image-grid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 16px;
  }
}
</style>
